#include <iostream>
#include <future>
#include <memory>
#include <thread>
#include <chrono>

/*
    例如：std::packaged_task<int(int, int)> task(Add);
    1. packaged_task对象可以当做可调用对象来直接调用执行任务
    task(10, 20); 不会报错
    2. packaged_task对象不能完全当做一个函数对象使用
    thread(task, 10, 20);  会报错
    std::async(std::launch::async, task, 10, 20);  会报错

    解决方案：
    将task包装为智能指针对象，将指针对象传入线程，在线程中对指针解引用直接进行调用
*/ 

int Add(int a, int b)
{
    std::cout << "Add() is called" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(3));
    return a+b;
}

int main()
{
    auto ptask = std::make_shared<std::packaged_task<int(int, int)>>(Add);
    std::future<int> fu = ptask->get_future();

    std::thread th([ptask](){
        (*ptask)(15, 25);
    });

    int result = fu.get();
    std::cout << "result = " << result << std::endl;
    th.join();

    return 0;
}

